﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using BrnMall.Manager.Manager.WeApp;
using BrnMall.Sdk.WeiXin;
using BrnMall.Sdk.WeiXin.Tool;
using BrnMall.Sdk.WeiXin.weapp;
using BrnMall.Services;
using BrnMall.WeiXin.Sdk;
using Newtonsoft.Json;

namespace BrnMall.Business
{
    /// <summary>
    /// 小程序发布上线逻辑
    /// </summary>
    public static class StoreAppReleaseManager
    {
        #region 授权成功后
        /// <summary>
        /// 手动获取更新状态
        /// </summary>
        /// <param name="storeAppId"></param>
        /// <returns></returns>
        public static BaseResult GetAuditStatus(int storeAppId)
        {
            RefreshAuthorizerToken(storeAppId);
            var storeApplication = StoreApplicationManager.GetStoreApplication(storeAppId);
            var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
            return WeAppSdk.GetAuditStatus(auth.Authorizer_Access_Token, storeApplication.AuditId);
        }
        /// <summary>
        /// 手动获取最新一次更新状态
        /// </summary>
        /// <param name="storeAppId"></param>
        /// <returns></returns>
        public static BaseResult GetLastAuditStatus(int storeAppId)
        {
            RefreshAuthorizerToken(storeAppId);
            var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
            return WeAppSdk.GetLastAuditStatus(auth.Authorizer_Access_Token);
        }
        #endregion

        #region 上传小程序
        /// <summary>
        /// 上传小程序
        /// </summary>
        /// <param name="storeAppId">小程序实例ID</param>
        /// <returns></returns>
        public static BaseResult CommitStoreApp(int storeAppId)
        {
            Trace.TraceInformation("CommitStoreApp");
            RefreshAuthorizerToken(storeAppId);
            var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
            if (auth == null)
                throw new Exception("未找到相关的授权信息");
            var storeApplication = StoreApplicationManager.GetStoreApplication(storeAppId);
            if (storeApplication.DevStatus != 1)
                throw new Exception("该小程序必须是待上传状态");
            var weApplication = WeApplicationManager.GetWeApplication(storeApplication.AppId);
            var extJson = new ExtJson
            {
                ext = new Ext { StoreAppId = storeAppId, StoreId = storeApplication.StoreId },
                extAppid = auth.Authorizer_Appid
            };
            extJson.tabBar = null;
            //if (!string.IsNullOrEmpty(storeApplication.UserTabBar))
            //    extJson.tabBar = JsonConvert.DeserializeObject<TabBarPages>(storeApplication.UserTabBar);
            //else if (!string.IsNullOrEmpty(weApplication.RawTabBar))
            //    extJson.tabBar = JsonConvert.DeserializeObject<TabBarPages>(weApplication.RawTabBar);
            //else
            //{
            //    extJson.tabBar = null;
            //}
            var commitData = new CommitPostData
            {
                ext_json = JsonConvert.SerializeObject(extJson, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }),
                template_id = weApplication.TemplateId,
                user_desc = "",
                user_version = $"{DateTime.Now:yyyyMMddHHmmss}"
            };
            if (storeApplication.TemplateId != weApplication.TemplateId)
            {
                StoreApplicationManager.UpdateTemplateId(storeAppId, weApplication.TemplateId);
            }
            //更新域名
            WeAppSdk.SetDomain(auth.Authorizer_Access_Token, "weapp.711688.net.cn");
            var result = WeAppSdk.Commit(auth.Authorizer_Access_Token, commitData);
            if (result.errcode == 0) StoreApplicationManager.UpdateDevStatus(storeAppId, 2);
            return result;
        }
        #endregion

        #region 提交审核
        /// <summary>
        /// 提交审核
        /// </summary>
        /// <param name="storeAppId">小程序实例ID</param>
        /// <returns></returns>
        public static BaseResult SubmitAudit(int storeAppId)
        {
            Trace.TraceInformation("SubmitAudit");
            RefreshAuthorizerToken(storeAppId);
            var storeApplication = StoreApplicationManager.GetStoreApplication(storeAppId);
            if (storeApplication.DevStatus != 2)
                throw new Exception("该小程序必须是已上传状态");
            var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
            if (auth == null)
                throw new Exception("未找到相关的授权信息");
            var category = WeAppSdk.GetCategory(auth.Authorizer_Access_Token);
            if (category.category_list.Count == 0)
                throw new Exception("未找到小程序的服务类目，请先登录微信小程序后台设置服务类目");
            var firstCategory = category.category_list.First();
            var submit = new SubmitAudit
            {
                item_list = new List<SubmitAuditItem>
                {
                    new SubmitAuditItem
                    {
                        address = "pages/index/index",
                        tag = "",
                        first_class = firstCategory.first_class,
                        first_id = firstCategory.first_id,
                        second_class = firstCategory.second_class,
                        second_id = firstCategory.second_id,
                        third_class = firstCategory.third_class,
                        third_id = firstCategory.third_id,
                        title = "首页"
                    }
                }
            };
            var result = WeAppSdk.SubmitAudit(auth.Authorizer_Access_Token, submit);
            if (result.errcode == 0&&result.auditid>0)
            {
                StoreApplicationManager.UpdateDevStatus(storeAppId, 3);
                StoreApplicationManager.UpdateAuditId(storeAppId, result.auditid);
            }
            if (result.errcode == -1)//提示系统繁忙，尝试重新上传
            {
                StoreApplicationManager.UpdateDevStatus(storeAppId, 1);
            }
            return result;

        }
        #endregion

        #region 发布上线
        /// <summary>
        /// 发布
        /// </summary>
        /// <param name="storeAppId">小程序实例ID</param>
        /// <returns></returns>
        public static BaseResult ReleaseStoreApp(int storeAppId)
        {
            Trace.TraceInformation("ReleaseStoreApp");
            RefreshAuthorizerToken(storeAppId);
            var storeApplication = StoreApplicationManager.GetStoreApplication(storeAppId);
            if (storeApplication.DevStatus != 4)
                throw new Exception("该小程序必须是审核通过状态");
            var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
            if(auth==null)
                throw new Exception("未找到相关的授权信息");
            var result = WeAppSdk.Release(auth.Authorizer_Access_Token);
            switch (result.errcode)
            {
                case 0:
                case 85052://已发布
                    StoreApplicationManager.ReleaseApp(storeAppId);
                    break;
                case 85020://审核状态未满足发布
                    StoreApplicationManager.UpdateDevStatus(storeAppId, 3);
                    break;
                default:
                    StoreApplicationManager.UpdateAuditInfo(storeAppId, $"[{result.errcode}{result.ErrorMessage}][{result.errmsg}]");
                    break;
            }
            return result;
        }
        #endregion

        #region 升级
        /// <summary>
        /// 升级小程序模板
        /// </summary>
        /// <param name="storeAppId">小程序实例ID</param>
        /// <returns></returns>
        public static bool UpgradeStoreApp(int storeAppId)
        {
            Trace.TraceInformation("UpgradeStoreApp");
            var storeApplication = StoreApplicationManager.GetStoreApplication(storeAppId);
            if (storeApplication.DevStatus != 5)
                throw new Exception("该小程序必须是已发布状态");
            var storeapp = StoreApplicationManager.GetStoreApplication(storeAppId);
            storeapp.DevStatus = 1;
            storeapp.NeedUpdate = false;
            StoreApplicationManager.UpdateStoreApplication(storeapp);
            var commit = CommitStoreApp(storeAppId);
            if (commit.errcode == 0)
            {
                SubmitAudit(storeAppId);
            }

            return true;
        }
        #endregion

        #region 预览
        /// <summary>
        /// 获取小程序的预览体验二维码地址
        /// </summary>
        /// <param name="storeAppId">小程序实例ID</param>
        /// <returns></returns>
        public static string GetPreviewStoreAppUrl(int storeAppId)
        {
            Trace.TraceInformation("GetPreviewStoreAppUrl");
            RefreshAuthorizerToken(storeAppId);
            var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
            var fileUrl = WeAppSdk.GetQrCodeUrl(auth.Authorizer_Access_Token);
            var remoteUrl = Uploads.SaveUploadUserWxaCode(fileUrl);
            var QrcodeUrl = $"http://static.711688.net.cn/upload/user/{remoteUrl}";
            return QrcodeUrl;
        }
        /// <summary>
        /// 添加新的体验者
        /// </summary>
        /// <param name="storeAppId">小程序实例ID</param>
        /// <param name="wechatId">微信号</param>
        /// <returns></returns>
        public static BaseResult AddStoreAppPreviewUser(int storeAppId, string wechatId)
        {
            Trace.TraceInformation("AddStoreAppPreviewUser");
            if (storeAppId <= 0 || string.IsNullOrEmpty(wechatId))
                throw new Exception("参数错误");
            RefreshAuthorizerToken(storeAppId);
            var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
            var result = WeAppSdk.BindTester(auth.Authorizer_Access_Token, wechatId);
            return result;
        }
        #endregion

        #region 删除模板

        public static BaseResult DeleteTemplateId(int templateId)
        {
            var platform = WeApplicationManager.GetDefaultApplicationPlatform();
            return WeAppSdk.DeleteTemplate(platform.Component_Access_Token, templateId);
        }

        #endregion

        #region 刷新票据

        /// <summary>
        /// 刷新票据
        /// </summary>
        /// <param name="storeAppId"></param>
        /// <param name="alwaysRefresh">强制刷新</param>
        public static void RefreshAuthorizerToken(int storeAppId, bool alwaysRefresh = false)
        {
            Trace.TraceInformation("RefreshAuthorizerToken");
            var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
            Trace.TraceInformation("Get auth");
            if (auth == null)
                return;
            var platform = WeApplicationManager.GetDefaultApplicationPlatform();
            Trace.TraceInformation("Get platform");
            if (DateTime.Compare(auth.Expires_In.AddMinutes(-10), DateTime.Now) > 0 && !alwaysRefresh) return;
            Trace.TraceInformation($"刷新令牌:原令牌过期时间{auth.Expires_In}");
            var newToken = WeiXinSdk.RefreshAuthorizerToken(platform.Component_Access_Token, platform.AppId,
                auth.Authorizer_Appid, auth.Authorizer_Refresh_Token);
            Trace.TraceInformation("get newToken");
            if (string.IsNullOrEmpty(newToken?.authorizer_access_token) ||
                string.IsNullOrEmpty(newToken.authorizer_refresh_token))
            {
                Trace.TraceInformation($"刷新令牌:获取新令牌失败{JsonConvert.SerializeObject(newToken)}");
                return;
            }

            auth.Authorizer_Access_Token = newToken.authorizer_access_token;
            auth.Authorizer_Refresh_Token = newToken.authorizer_refresh_token;
            auth.Expires_In = DateTime.Now.AddSeconds(newToken.expires_in);
            AppAuthorizationManager.UpdateAuthorizerAccessToken(auth.Authorizer_Appid, auth.Authorizer_Access_Token, auth.Expires_In, auth.Authorizer_Refresh_Token);
        }
        #endregion

        #region  获取页面配置

        public static Pages GetTempatePages(int storeAppId)
        {
            RefreshAuthorizerToken(storeAppId);
            var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
            return WeAppSdk.GetTempatePages(auth.Authorizer_Access_Token);
        }


        #endregion
    }
}
